# [五] Bean的实例化-后置处理器

# Spring 初始化核心流程

spring容器初始化的核心方法AbstractApplicationContext#refresh ,

  • ├─ refresh Spring 初始化核心流程入口
  • │ ├─ prepareRefresh ① 准备此上下文用于刷新,设置启动时间和active标志,初始化属性
  • │ ├─ obtainFreshBeanFactory ② 创建 BeanFactory
  • │ ├─ prepareBeanFactory ③ 设置 BeanFactory 的基本属性
  • │ ├─ postProcessBeanFactory ④ 子类处理自定义的BeanFactoryPostProcess
  • │ ├─ invokeBeanFactoryPostProcessors ⑤ B本节主要跟踪的源码流程
  • │ ├─ registerBeanPostProcessors ⑥ 本节主要跟踪的源码流程
  • │ ├─ initMessageSource ⑦ 初始化上下文中的资源文件,如国际化文件的处理等
  • │ ├─ initApplicationEventMulticaster ⑧ 初始化上下文的事件传播器
  • │ ├─ onRefresh ⑨ 给子类扩展初始化其他Bean,springboot 中用来做内嵌 tomcat 启动
  • │ ├─ registerListeners ⑩ 在所有bean中查找监听 bean,然后注册到广播器中
  • │ ├─ finishBeanFactoryInitialization ⑪ 初始化所有的单例Bean、ioc、BeanPostProcessor的执行、Aop入口
  • │ └─ finishRefresh ⑫ 完成刷新过程,发布相应的事件

# invokeBeanFactoryPostProcessors 方法

invokeBeanFactoryPostProcessors

invokeBeanFactoryPostProcessors方法,负责激活各种 BeanFactory 处理器,以及两个核心接口的调用:

  • BeanDefinitionRegistryPostProcessor
    • 实际完成了对其实现类中postProcessBeanDefinitionRegistry方法的调用,完成对BeanDefinition的新增、修改;
  • BeanFactoryPostProcessor
    • 实际完成了对其实现类中postProcessBeanFactory方法的调用;

直接进入最终的 invokeBeanFactoryPostProcessors() 方法,

类文件: org.springframework.context.support.AbstractApplicationContext

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 获取实现了BeanDefinitionRegistryPostProcessor接口的所有类的BeanDefinition对象的beanName
// 1、最先调用的是实现了 PriorityOrdered 接口的所有BeanDefinitionRegistryPostProcessor
// 中的 postProcessBeanDefinitionRegistry的方法
String[] postProcessorNames =
		beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
	// 判断是否实现了排序接口 PriorityOrdered
	if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
		currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
		processedBeans.add(ppName);
	}
}

// 排序,就是用List中的sort排序,通过Comparator来进行
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);

// 调用过程
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 调用完清空
currentRegistryProcessors.clear();

// 2、其次调用的是实现了 Ordered 接口的所有BeanDefinitionRegistryPostProcessor
// 中的 postProcessBeanDefinitionRegistry的方法
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
	//判断是否是实现的Ordered接口
	if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
		currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
		processedBeans.add(ppName);
	}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

// 3、最后调用的是没实现排序接口的所有实现BeanDefinitionRegistryPostProcessor接口
// 中的 postProcessBeanDefinitionRegistry的方法
boolean reiterate = true;
while (reiterate) {
	reiterate = false;
	postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
	for (String ppName : postProcessorNames) {
		if (!processedBeans.contains(ppName)) {
			currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
			processedBeans.add(ppName);
			reiterate = true;
		}
	}
	sortPostProcessors(currentRegistryProcessors, beanFactory);
	registryProcessors.addAll(currentRegistryProcessors);
	//
	invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
	currentRegistryProcessors.clear();
}

// 调用 postProcessBeanFactory 方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}

else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}

// 获取实现了BeanFactoryPostProcessor接口的类,获取beanDefinition的名称
String[] postProcessorNames =
	beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
	// skip - already processed in first phase above
}
// 实现了PriorityOrdered接口的
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
	priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
// 实现了Ordered接口的
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
	orderedPostProcessorNames.add(ppName);
}
else {
	// 没实现接口的
	nonOrderedPostProcessorNames.add(ppName);
}
}

// 排序
// 先调用实现了 PriorityOrdered接口的 BeanFactoryPostProcessors
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);

// 调用
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// 接着调用实现了 Ordered接口的 BeanFactoryPostProcessors
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
	orderedPostProcessors.add(beanFactory.getBean(postProcessorName, 		 BeanFactoryPostProcessor.class));
	}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
	nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, 	BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

beanFactory.clearMetadataCache();
}

进入invokeBeanDefinitionRegistryPostProcessors()方法的调用过程,

类文件: org.springframework.context.support.PostProcessorRegistrationDelegate

private static void invokeBeanFactoryPostProcessors(
	Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
	// 拿到所有实现了PriorityOrdered 接口的类
	for (BeanFactoryPostProcessor postProcessor : postProcessors) {
		// 调用它的postProcessBeanFactory方法
		postProcessor.postProcessBeanFactory(beanFactory);
	}
}

至此,⑤ 调用激活所有实现了BeanDefinitionRegistryPostProcessor接口中的两个方法,执行过程完成。

# registerBeanPostProcessors 方法

registerBeanPostProcessors

registerBeanPostProcessors方法,主要是针对实现BeanPostProcessor接口的类调用和实例化过程。 BeanPostProcessor接口类型实例是针对某种特定功能的埋点,在这个点会根据接口类型来过滤掉不关注这个点的其他类,只有真正关注的类才会在这个点进行相应的功能实现。

进入⑥registerBeanPostProcessors()方法,

类文件: org.springframework.context.support.PostProcessorRegistrationDelegate

public static void registerBeanPostProcessors(
	ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//拿到工程里面所有实现了BeanPostProcessor接口的类,获取到BeanDefinition的名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//当一个bean是在BeanPostProcessor实例化期间创建的,也就是说当一个 bean不能被所有的beanpostprocessor处理时,
//注册BeanPostProcessorChecker,记录信息信息
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 提前实例化 BeanPostProcessor 类型的 bean,然后对 bean 进行排序
for (String ppName : postProcessorNames) {
	if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
		// getBean是实例化方法,后面我们在讲bean实例化过程是会着重讲到
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		priorityOrderedPostProcessors.add(pp);
		// 判断类型是否是 MergedBeanDefinitionPostProcessor,如果是则代码是内部使用的
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
		orderedPostProcessorNames.add(ppName);
	}
	else {
		nonOrderedPostProcessorNames.add(ppName);
	}
}

// 首先,注册实现 priorityor 的 beanpostprocessor。
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//注册到BeanFactory中
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 然后,注册实现 Ordered 的 BeanPostProcessors。
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
	BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
	orderedPostProcessors.add(pp);
	if (pp instanceof MergedBeanDefinitionPostProcessor) {
		internalPostProcessors.add(pp);
	}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 接着注册所有常规的 beanpostprocessor。
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
	BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
	nonOrderedPostProcessors.add(pp);
	if (pp instanceof MergedBeanDefinitionPostProcessor) {
		internalPostProcessors.add(pp);
	}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最后,重新注册所有的内部 beanpostprocessor。
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 将检测内部 bean的后处理器重新注册为 applicationlistener,
// 将它移到处理器链的末端(用于获取代理等)。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

知识点

beanFactory.getBeanPostProcessorCount()会得到默认容器中注册的 BeanPostProcessor 个数,实际就是调用 List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>()size()方法,默认的容器注册的 BeanPostProcessor 有:

  • ApplicationContextAwarePostProcessor
  • ApplicationListenerDetector
  • ConfigurationClassPostProcessor
  • PostProcessorRegistrationDelegate

进入registerBeanPostProcessors()方法,注册过程

类文件: org.springframework.context.support.PostProcessorRegistrationDelegate

/**
 * 注册当前的 BeanPostProcessor
 */
private static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

		for (BeanPostProcessor postProcessor : postProcessors) {
			// 添加到List<BeanPostProcessor> beanPostProcessors
			beanFactory.addBeanPostProcessor(postProcessor);
		}
	}

知识点

invokeBeanFactoryPostProcessors和⑥registerBeanPostProcessors两个方法的处理流程基本一致,都分别对实现接口的类实例化调用:

  • 首先对实现 PriorityOrdered 接口的 beanPostProcessors 排序调用
  • 其次对实现 Ordered 接口的 beanPostProcessors 排序调用
  • 最后对没有实现排序接口的 beanPostProcessors 调用

# BeanPostProcessor

BeanPostProcessor有两个方法,postProcessBeforeInitializationpostProcessAfterInitialization。它们分别在任何bean初始化回调之前或之后执行(例如InitializingBean的afterPropertiesSet方法或自定义init-method方法之前或者之后), 在这个时候该bean的属性值已经填充完成了,并且我们返回的bean实例可能已经是原始实例的包装类型了。例如返回一个FactoryBean

# InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor继承自BeanPostProcessor接口。主要多提供了以下三个方法:

  • postProcessBeforeInstantiation:该方法是在Bean实例化目标对象之前调用,返回的Bean对象可以代理目标,从而有效的阻止了目标Bean的默认实例化。
  • postProcessAfterInstantiation:该方法执行在通过构造函数或工厂方法在实例化bean之后但在发生Spring属性填充(通过显式属性或自动装配)之前执行操作。这是在Spring的自动装配开始之前对给定的bean实例执行自定义字段注入的理想回调。如果该方法返回false,那么它会阻断后续InstantiationAwareBeanPostProcessor后置处理器的执行,并且会阻止后续属性填充的执行逻辑。
  • postProcessPropertyValues:在工厂将给定属性值应用于给定bean之前,对它们进行后处理。允许检查是否满足所有依赖关系,例如基于bean属性设置器上的“ Required”注解。还允许替换要应用的属性值,通常是通过基于原始PropertyValues创建新的MutablePropertyValues实例,添加或删除特定值来实现。

# SmartInstantiationAwareBeanPostProcessor

智能实例化Bean的后处理器,主要提供了三个方法:

  • predictBeanType:预测从此处理器的postProcessBeforeInstantiation回调最终返回的bean的类型。
  • determineCandidateConstructors:确定合适的实例化Bean的构造函数。
  • getEarlyBeanReference:获取提早暴露的Bean的引用,提早暴露的Bean就是只完成了实例化,还未完成属性赋值和初始化的Bean。

# MergedBeanDefinitionPostProcessor

合并Bean的定义信息的后处理方法,该方法是在Bean的实例化之后设置值之前调用。

# beanPostProcessors 答疑

问题

为什么⑤invokeBeanFactoryPostProcessors方法,在② 执行之后呢?

参考答案

因为并不是所有功能都配置在xml文件中,有些业务场景需要在程序运行时,动态的调用或者修改beanDefinition。实际上就是Spring初始化时,自动调用实现了BeanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistrypostProcessBeanFactory个方法。

问题

为什么⑥registerBeanPostProcessors()方法中,会提前实例化BeanPostProcessor类型的 bean?

参考答案

因为 bean在实例化过程中进行依赖注入,有可能引用到BeanPostProcessor类型的 bean。